﻿
Imports System.IO

''' <summary>
''' 暗号化クラス
''' </summary>
''' <remarks></remarks>
Public Class Cryptor

#Region " Declare "

	''' <summary>公開鍵</summary>
	Private Shared _publicKey As String

	''' <summary>秘密鍵</summary>
	Private Shared _privateKey As String

#End Region

#Region " Property "

	''' <summary>
	''' 公開鍵のパス
	''' </summary>
	''' <value></value>
	''' <returns></returns>
	''' <remarks></remarks>
	Public Shared ReadOnly Property PublicKeyPath As String
		Get
			Return Path.Combine(My.Settings.KeyPath, ".publicKey")
		End Get
	End Property

	''' <summary>
	''' 秘密鍵のパス
	''' </summary>
	''' <value></value>
	''' <returns></returns>
	''' <remarks></remarks>
	Public Shared ReadOnly Property PrivateKeyPath As String
		Get
			Return Path.Combine(My.Settings.KeyPath, ".privateKey")
		End Get
	End Property

#End Region

#Region " Methods "

	''' <summary>
	''' 鍵の読込
	''' </summary>
	''' <returns></returns>
	''' <remarks></remarks>
	Public Shared Function ReadKeys() As Boolean
		If Not File.Exists(PublicKeyPath) Then
			Return False
		End If
		If Not File.Exists(PrivateKeyPath) Then
			Return False
		End If

		_publicKey = File.ReadAllText(PublicKeyPath)
		If _publicKey.Length = 0 Then
			Return False
		End If

		_privateKey = File.ReadAllText(PrivateKeyPath)
		If _privateKey.Length = 0 Then
			Return False
		End If

		Return True
	End Function

	''' <summary>
	''' 鍵の削除
	''' </summary>
	''' <remarks></remarks>
	Public Shared Sub DeleteKeys()
		File.Delete(PublicKeyPath)
		File.Delete(PrivateKeyPath)
	End Sub

	''' <summary>
	''' 公開鍵と秘密鍵を作成して返す
	''' </summary>
	''' <remarks></remarks>
	Public Shared Sub CreateKeys()
		'RSACryptoServiceProviderオブジェクトの作成
		Dim rsa As New System.Security.Cryptography.RSACryptoServiceProvider()

		Directory.CreateDirectory(My.Settings.KeyPath)

		'公開鍵をXML形式で取得
		_publicKey = rsa.ToXmlString(False)
		File.WriteAllText(PublicKeyPath, _publicKey)
		'秘密鍵をXML形式で取得
		_privateKey = rsa.ToXmlString(True)
		File.WriteAllText(PrivateKeyPath, _privateKey)
	End Sub

	''' <summary>
	''' 公開鍵を使って文字列を暗号化する
	''' </summary>
	''' <param name="str">暗号化する文字列</param>
	''' <returns>暗号化された文字列</returns>
	''' <remarks></remarks>
	Public Function Encrypt(ByVal str As String) As String
		'RSACryptoServiceProviderオブジェクトの作成
		Dim rsa As New System.Security.Cryptography.RSACryptoServiceProvider()

		'公開鍵を指定
		rsa.FromXmlString(_publicKey)

		'暗号化する文字列をバイト配列に
		Dim data As Byte() = System.Text.Encoding.UTF8.GetBytes(str)
		'暗号化する
		'（XP以降の場合のみ2項目にTrueを指定し、OAEPパディングを使用できる）
		Dim encryptedData As Byte() = rsa.Encrypt(data, False)

		'Base64で結果を文字列に変換
		Return System.Convert.ToBase64String(encryptedData)
	End Function

	''' <summary>
	''' 秘密鍵を使って文字列を復号化する
	''' </summary>
	''' <param name="str">Encryptメソッドにより暗号化された文字列</param>
	''' <returns>復号化された文字列</returns>
	''' <remarks></remarks>
	Public Function Decrypt(ByVal str As String) As String
		'RSACryptoServiceProviderオブジェクトの作成
		Dim rsa As New System.Security.Cryptography.RSACryptoServiceProvider()

		'秘密鍵を指定
		rsa.FromXmlString(_privateKey)

		'復号化する文字列をバイト配列に
		Dim data As Byte() = System.Convert.FromBase64String(str)
		'復号化する
		Dim decryptedData As Byte() = rsa.Decrypt(data, False)

		'結果を文字列に変換
		Return System.Text.Encoding.UTF8.GetString(decryptedData)
	End Function

#End Region

End Class
